# 0 "boot/head.S"
# 0 "<built-in>"
# 0 "<command-line>"

# 1 "/usr/include/stdc-predef.h" 1 3 4

# 17 "/usr/include/stdc-predef.h" 3 4



















# 45 "/usr/include/stdc-predef.h" 3 4

# 55 "/usr/include/stdc-predef.h" 3 4









# 1 "<command-line>" 2
# 1 "boot/head.S"










.text
.globl idt,gdt,
.globl swapper_pg_dir,pg0
.globl empty_bad_page
.globl empty_bad_page_table
.globl empty_zero_page
.globl tmp_floppy_area,floppy_track_buffer


# 1 "/home/ubuntu/workspace/Linux-0.99-vscode_debug/include/linux/tasks.h" 1








# 20 "boot/head.S" 2

# 1 "/home/ubuntu/workspace/Linux-0.99-vscode_debug/include/linux/segment.h" 1









# 21 "boot/head.S" 2










 // To keep ld happy
 .globl _start
 _start:

startup_32:
	cld
	movl $(0x18),%eax
	mov %ax,%ds
	mov %ax,%es
	mov %ax,%fs
	mov %ax,%gs
	lss stack_start,%esp



	xorl %eax,%eax
	movl $_edata,%edi
	movl $_end,%ecx
	subl %edi,%ecx
	cld
	rep
	stosb




	call setup_idt
	xorl %eax,%eax
1:	incl %eax		# check that A20 really IS enabled
	movl %eax,0x000000	# loop forever if it isn't
	cmpl %eax,0x100000
	je 1b





	pushl $0
	popfl





	movl $0x90000,%esi
	movl $empty_zero_page,%edi
	movl $512,%ecx
	cld
	rep
	movsl
	xorl %eax,%eax
	movl $512,%ecx
	rep
	stosl
	cmpw $(0xA33F),0x90020
	jne 1f
	movl $empty_zero_page+2048,%edi
	movzwl 0x90022,%esi
	addl $(0x90000),%esi
	movl $2048,%ecx
	rep
	movsb
1:






	movl %esp,%edi		# save stack pointer
	andl $0xfffffffc,%esp	# align stack to avoid AC fault
	movl $3,x86
	pushfl			# push EFLAGS
	popl %eax		# get EFLAGS
	movl %eax,%ecx		# save original EFLAGS
	xorl $0x40000,%eax	# flip AC bit in EFLAGS
	pushl %eax		# copy to EFLAGS
	popfl			# set EFLAGS
	pushfl			# get new EFLAGS
	popl %eax		# put it in eax
	xorl %ecx,%eax		# change in flags
	andl $0x40000,%eax	# check if AC bit changed
	je is386
	movl $4,x86
	movl %ecx,%eax
	xorl $0x200000,%eax	# check ID flag
	pushl %eax
	popfl			# if we are on a 486,
	pushfl			# we can't change it
	popl %eax
	xorl %ecx,%eax
	andl $0x200000,%eax
	je is486
	movl $5,x86		# 586 setup same as 486 at least for now
is486:	pushl %ecx		# restore original EFLAGS
	popfl
	movl %edi,%esp		# restore esp
	movl %cr0,%eax		# 486
	andl $0x80000011,%eax	# Save PG,PE,ET
	orl $0x50022,%eax	# set AM, WP, NE and MP
	jmp 2f
is386:	pushl %ecx		# restore original EFLAGS
	popfl
	movl %edi,%esp		# restore esp
	movl %cr0,%eax		# 386
	andl $0x80000011,%eax	# Save PG,PE,ET
	orl $2,%eax		# set MP
2:	movl %eax,%cr0
	call check_x87
	call setup_paging
	lgdt gdt_descr
	lidt idt_descr
	ljmp $(0x10),$1f
1:	movl $(0x18),%eax	# reload all the segment registers
	mov %ax,%ds		# after changing gdt.
	mov %ax,%es
	mov %ax,%fs
	mov %ax,%gs
	lss stack_start,%esp
	xorl %eax,%eax
	lldt %ax
	pushl %eax		# These are the parameters to main :-)
	pushl %eax
	pushl %eax
	cld			# gcc2 wants the direction flag cleared at all times
	call start_kernel
L6:
	jmp L6			# main should never return here, but
				# just in case, we know what happens.




check_x87:
	movl $0,hard_math
	clts
	fninit
	fstsw %ax
	cmpb $0,%al
	je 1f
	movl %cr0,%eax		
	xorl $4,%eax		
	movl %eax,%cr0
	ret
.align 2
1:	movl $1,hard_math
	.byte 0xDB,0xE4		
	ret


# 190 "boot/head.S"
setup_idt:
	lea ignore_int,%edx
	movl $(0x10 << 16),%eax
	movw %dx,%ax		
	movw $0x8E00,%dx	

	lea idt,%edi
	mov $256,%ecx
rp_sidt:
	movl %eax,(%edi)
	movl %edx,4(%edi)
	addl $8,%edi
	dec %ecx
	jne rp_sidt
	ret



# 218 "boot/head.S"
.align 2
setup_paging:
	movl $1024*2,%ecx		
	xorl %eax,%eax
	movl $swapper_pg_dir,%edi	
	cld;rep;stosl

	movl $pg0+7,swapper_pg_dir		

	movl $pg0+7,swapper_pg_dir+3072	
	movl $pg0+4092,%edi
	movl $0x03ff007,%eax		
	std
1:	stosl			
	subl $0x1000,%eax
	jge 1b
	cld
	movl $swapper_pg_dir,%eax
	movl %eax,%cr3			
	movl %cr0,%eax
	orl $0x80000000,%eax
	movl %eax,%cr0		
	ret			





.org 0x1000
swapper_pg_dir:




.org 0x2000
pg0:

.org 0x3000
empty_bad_page:

.org 0x4000
empty_bad_page_table:

.org 0x5000
empty_zero_page:

.org 0x6000





tmp_floppy_area:
	.fill 1024,1,0






floppy_track_buffer:
	.fill 512*2*18,1,0


int_msg:
	.asciz "Unknown interrupt\n"
.align 2
ignore_int:
	cld
	pushl %eax
	pushl %ecx
	pushl %edx
	push %ds
	push %es
	push %fs
	movl $(0x18),%eax
	mov %ax,%ds
	mov %ax,%es
	mov %ax,%fs
	pushl $int_msg
	call printk
	popl %eax
	pop %fs
	pop %es
	pop %ds
	popl %edx
	popl %ecx
	popl %eax
	iret




.align 4
.word 0
idt_descr:
	.word 256*8-1		# idt contains 256 entries
	.long 0xc0000000+idt

.align 4
idt:
	.fill 256,8,0		# idt is uninitialized

.align 4
.word 0
gdt_descr:
	.word (8+2*64)*8-1
	.long 0xc0000000+gdt





.align 4
gdt:
	.quad 0x0000000000000000	
	.quad 0x0000000000000000	
	.quad 0xc0c39a000000ffff	
	.quad 0xc0c392000000ffff	
	.quad 0x00cbfa000000ffff	
	.quad 0x00cbf2000000ffff	
	.quad 0x0000000000000000	
	.quad 0x0000000000000000	
	.fill 2*64,8,0		
